import { computed, ref } from "vue";

type SortOrder = "ascending" | "descending";
type SortConfig = Map<string, SortOrder>;

interface SortPreset {
  name: string;
  sortConfig: SortConfig;
}

export function usePositionSorting() {
  // Presets (keep same semantics as account table)
  const POSITION_SORT_PRESETS: SortPreset[] = [
    { name: "合约优先", sortConfig: new Map([["symbol", "ascending"]]) },
    { name: "盈亏优先", sortConfig: new Map([["pnl_by_cost", "descending"]]) },
    {
      name: "合约&品种",
      sortConfig: new Map([
        ["product_type", "descending"],
        ["symbol", "ascending"]
      ])
    },
    {
      name: "盈亏&品种",
      sortConfig: new Map([
        ["product_type", "descending"],
        ["pnl_by_cost", "descending"]
      ])
    }
  ];

  const DEFAULT_SORT_PRESET = POSITION_SORT_PRESETS[0];

  // Local multi-column sort state
  const sortConfig = ref<SortConfig>(new Map());

  // Active preset name (for TagSelector)
  const activePresetName = ref<string>("");

  // TagSelector two-way binding
  const selectedPresetModel = computed<string>({
    get: () => activePresetName.value,
    set: (value: string) => {
      if (!value) {
        clearSort();
        clearActivePreset();
      } else {
        const preset = POSITION_SORT_PRESETS.find(p => p.name === value);
        if (preset) {
          applySortPreset(preset);
        }
      }
    }
  });

  // Initialize default sort once if empty
  if (sortConfig.value.size === 0) {
    applySortPreset(DEFAULT_SORT_PRESET);
  }

  function sort<T extends Record<string, any>>(data: T[]): T[] {
    if (!data || data.length === 0 || sortConfig.value.size === 0) return data;
    const sorted = [...data];
    const entries = Array.from(sortConfig.value.entries());
    sorted.sort((a, b) => {
      for (const [prop, order] of entries) {
        let aVal: any = (a as any)[prop];
        let bVal: any = (b as any)[prop];

        // Normalize numeric-like fields
        if (
          prop === "pnl" ||
          prop === "last_price" ||
          prop === "pnl_by_cost" ||
          prop === "cost" ||
          prop === "margin" ||
          prop === "volume"
        ) {
          aVal = Number(aVal) ?? 0;
          bVal = Number(bVal) ?? 0;
        } else if (typeof aVal === "string" && typeof bVal === "string") {
          aVal = aVal.toLowerCase();
          bVal = bVal.toLowerCase();
        }

        if (aVal === bVal) continue;
        const dir = order === "ascending" ? 1 : -1;
        if (aVal == null) return dir; // undefined/null last
        if (bVal == null) return -dir;
        return aVal < bVal ? -dir : dir;
      }
      return 0;
    });
    return sorted;
  }

  function clearSort(): void {
    sortConfig.value.clear();
  }

  function setActivePreset(name: string): void {
    activePresetName.value = name;
  }

  function clearActivePreset(): void {
    activePresetName.value = "";
  }

  function applySortPreset(preset: SortPreset): void {
    sortConfig.value.clear();
    for (const [k, v] of preset.sortConfig.entries()) {
      sortConfig.value.set(k, v);
    }
    setActivePreset(preset.name);
  }

  function doesCurrentSortMatchPresets(): string | null {
    if (sortConfig.value.size === 0) return null;
    for (const preset of POSITION_SORT_PRESETS) {
      if (preset.sortConfig.size !== sortConfig.value.size) continue;
      let match = true;
      for (const [k, v] of preset.sortConfig.entries()) {
        if (sortConfig.value.get(k) !== v) {
          match = false;
          break;
        }
      }
      if (match) return preset.name;
    }
    return null;
  }

  function handleSortChange({
    prop,
    order
  }: {
    prop: string;
    order: SortOrder | null;
  }): void {
    if (!prop) return;
    if (order) {
      sortConfig.value.set(prop, order);
    } else {
      sortConfig.value.delete(prop);
    }

    const match = doesCurrentSortMatchPresets();
    if (match) {
      setActivePreset(match);
    } else {
      clearActivePreset();
    }
  }

  function setHeaderCellClass(params: any): string {
    if (sortConfig.value.size === 0) {
      params.column.order = null;
      return "";
    }
    params.column.order = sortConfig.value.has(params.column.property)
      ? sortConfig.value.get(params.column.property)!
      : null;
    return "";
  }

  return {
    // constants
    POSITION_SORT_PRESETS,

    // state
    selectedPresetModel,

    // data
    sort,

    // methods
    handleSortChange,
    setHeaderCellClass
  };
}
